Add support for documenting all members of the workspace with "doc --all"
authorSebastian Dröge <sebastian@centricular.com>
Fri, 6 Jan 2017 19:57:13 +0000 (21:57 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Sun, 8 Jan 2017 12:01:04 +0000 (14:01 +0200)
https://github.com/rust-lang/cargo/issues/3491

src/bin/doc.rs
src/cargo/ops/cargo_doc.rs

index 5ec40e4c2158785cfcaf635c783638cc9eb81a11..5323b4adb0b2404c11917dd27014f8c72dda8992 100644 (file)
@@ -23,6 +23,7 @@ pub struct Options {
     flag_bin: Vec<String>,
     flag_frozen: bool,
     flag_locked: bool,
+    flag_all: bool,
 }
 
 pub const USAGE: &'static str = "
@@ -35,6 +36,7 @@ Options:
     -h, --help                   Print this message
     --open                       Opens the docs in a browser after the operation
     -p SPEC, --package SPEC ...  Package to document
+    --all                        Document all packages in the workspace
     --no-deps                    Don't build documentation for dependencies
     -j N, --jobs N               Number of parallel jobs, defaults to # of CPUs
     --lib                        Document only this package's library
@@ -55,6 +57,9 @@ Options:
 By default the documentation for the local package and all dependencies is
 built. The output is all placed in `target/doc` in rustdoc's usual format.
 
+All packages in the workspace are documented if the `--all` flag is supplied. The
+`--all` flag may be supplied in the presence of a virtual manifest.
+
 If the --package argument is given, then SPEC is a package id specification
 which indicates which package should be documented. If it is not given, then the
 current package is documented. For more information on SPEC and its format, see
@@ -70,6 +75,12 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
 
     let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
 
+    let spec = if options.flag_all {
+        Packages::All
+    } else {
+        Packages::Packages(&options.flag_package)
+    };
+
     let empty = Vec::new();
     let doc_opts = ops::DocOptions {
         open_result: options.flag_open,
@@ -80,7 +91,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
             features: &options.flag_features,
             all_features: options.flag_all_features,
             no_default_features: options.flag_no_default_features,
-            spec: Packages::Packages(&options.flag_package),
+            spec: spec,
             filter: ops::CompileFilter::new(options.flag_lib,
                                             &options.flag_bin,
                                             &empty,
index 29de8aea96a5946f11c2c5b716814e89dccbfcab..6817cca3be5183a476885c125aa68fddfca3ac36 100644 (file)
@@ -3,7 +3,7 @@ use std::fs;
 use std::path::Path;
 use std::process::Command;
 
-use core::{PackageIdSpec, Workspace};
+use core::Workspace;
 use ops;
 use util::CargoResult;
 
@@ -13,32 +13,42 @@ pub struct DocOptions<'a> {
 }
 
 pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> {
-    let package = ws.current()?;
+    let specs = options.compile_opts.spec.into_package_id_specs(ws)?;
+    let resolve = ops::resolve_ws_precisely(ws,
+                                            None,
+                                            options.compile_opts.features,
+                                            options.compile_opts.all_features,
+                                            options.compile_opts.no_default_features,
+                                            &specs)?;
+    let (packages, resolve_with_overrides) = resolve;
 
-    let spec = match options.compile_opts.spec {
-        ops::Packages::Packages(packages) => packages,
-        _ => {
-            // This should not happen, because the `doc` binary is hard-coded to pass
-            // the `Packages::Packages` variant.
-            bail!("`cargo doc` does not support the `--all` flag")
-        },
+    let mut pkgs = Vec::new();
+    if specs.len() > 0 {
+        for p in specs.iter() {
+            pkgs.push(packages.get(p.query(resolve_with_overrides.iter())?)?);
+        }
+    } else {
+        let root_package = ws.current()?;
+        pkgs.push(root_package);
     };
 
     let mut lib_names = HashSet::new();
     let mut bin_names = HashSet::new();
-    if spec.is_empty() {
-        for target in package.targets().iter().filter(|t| t.documented()) {
-            if target.is_lib() {
-                assert!(lib_names.insert(target.crate_name()));
-            } else {
-                assert!(bin_names.insert(target.crate_name()));
+    if specs.is_empty() {
+        for package in &pkgs {
+            for target in package.targets().iter().filter(|t| t.documented()) {
+                if target.is_lib() {
+                    assert!(lib_names.insert(target.crate_name()));
+                } else {
+                    assert!(bin_names.insert(target.crate_name()));
+                }
             }
-        }
-        for bin in bin_names.iter() {
-            if lib_names.contains(bin) {
-                bail!("cannot document a package where a library and a binary \
-                       have the same name. Consider renaming one or marking \
-                       the target as `doc = false`")
+            for bin in bin_names.iter() {
+                if lib_names.contains(bin) {
+                    bail!("cannot document a package where a library and a binary \
+                           have the same name. Consider renaming one or marking \
+                           the target as `doc = false`")
+                }
             }
         }
     }
@@ -46,12 +56,10 @@ pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> {
     ops::compile(ws, &options.compile_opts)?;
 
     if options.open_result {
-        let name = if spec.len() > 1 {
+        let name = if pkgs.len() > 1 {
             bail!("Passing multiple packages and `open` is not supported")
-        } else if spec.len() == 1 {
-            PackageIdSpec::parse(&spec[0])?
-                .name()
-                .replace("-", "_")
+        } else if pkgs.len() == 1 {
+            pkgs[0].name().replace("-", "_")
         } else {
             match lib_names.iter().chain(bin_names.iter()).nth(0) {
                 Some(s) => s.to_string(),